﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using System.Text.RegularExpressions;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private SerialPortUtil spu = null;
        private SerialPort port1_16;
        private SerialPort port17_32;
        private SerialPort portIn;
        private String state = "";
        private Boolean canContinue = false;//手动继续
        private MediaplayerUtils mu = null;
        private bool hasError = false;
        private bool isPause = false;
        private OpenFileDialog ofd;
        private DataBaseHelper dbHelper;
        private int initI = 0;
        private int initJ = 0;
        private bool isStoped = false;//是否停止
        public Form1()
        {
            InitializeComponent();
            //设置form居中
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
            
            //初始化音乐播放
            mu = new MediaplayerUtils();
            spu = new SerialPortUtil();
            //初始化数据库操作
            dbHelper = new DataBaseHelper();

            //设置文件选择框的相关属性
            ofd = new OpenFileDialog();
            ofd.InitialDirectory = "D:\\";
            ofd.RestoreDirectory = false;
            ofd.Filter = "txt files (*.txt)|*.txt";
            ofd.FilterIndex = 1;

            state = "1";
            setRunnintState();
           }

        private void Form1_Load(object sender, EventArgs e)
        {
            

        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void label4_Click(object sender, EventArgs e)
        {

        }

        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }

        private void label8_Click(object sender, EventArgs e)
        {

        }

        private void comportText_TextChanged(object sender, EventArgs e)
        {

        }

       
        //点击开始按钮
        private void startButton_Click(object sender, EventArgs e)
        {
            //首先判断有没有文件
            if (fileName.Text == "") {
                MessageBox.Show("请先选择文件");
                return;
            }
            //首先对数据进行验证
            if (!validateData()) {
                return;
            }
            //判断有没有间隔时间
            if (sleepTime.Text == "") {
                MessageBox.Show("请填写间隔时间");
                return;
            }
            initI = 0;
            initJ = 0;
            state = "2";
            setRunnintState();
            //首先判断是继续进行，还是从头开始
            DataTableReader reader = dbHelper.query();
            if (reader.HasRows)
            {

                //从数据库中取出下一条数据的位置
                while (reader.Read())
                {
                    string data = (string)reader.GetValue(1);
                    if (data != null && !"".Equals(data))
                    {
                        String[] dataArray = data.Split(new char[1] { ',' });
                        initI = int.Parse(dataArray[0]);
                        initJ = int.Parse(dataArray[1]) + 1;
                    }
                }
                if (MessageBox.Show("系统将从" + initI + "," + initJ + "处开始执行执行，是否继续？", "提示", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
                {
                    return;
                }
            }
            else
            {
                if (MessageBox.Show("这是一个新文件，是否执行？", "提示", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
                {
                    return;
                }
            }
            //创建一个线程，进行输出数据
            Thread writeDataThread = new Thread(new ThreadStart(writeData));
            writeDataThread.Start();
          
            
        }

        public void setRunnintState()
        {
            switch (state) {
                case "1": {
                    runningState.Text = "空闲中";
                    runningState.BackColor = Color.Gray;
                    
                }
                    break;
                case "2": {
                    runningState.Text = "运行中";
                    runningState.BackColor = Color.Green;
                }
                    break;
                case "3":
                    {
                        runningState.Text = "暂停中";
                        runningState.BackColor = Color.Yellow;
                    }
                    break;
                case "4":
                    {
                        runningState.Text = "出错";
                        runningState.BackColor = Color.Red;
                    }
                    break;
                case "5":
                    {
                        runningState.Text = "测试中";
                        runningState.BackColor = Color.Green;
                    }
                    break;
                case "6":
                    {
                        runningState.Text = "测试1-16输出";
                        runningState.BackColor = Color.Green;
                    }
                    break;
                case "7":
                    {
                        runningState.Text = "测试17-32输出";
                        runningState.BackColor = Color.Green;
                    }
                    break;
                case "8":
                    {
                        runningState.Text = "测试输入";
                        runningState.BackColor = Color.Green;
                    }
                    break;
                case "9":
                    {
                        runningState.Text = "测试数据库";
                        runningState.BackColor = Color.Green;
                    }
                    break;
            }


        }

        //点击测试按钮
        private void testComPort_Click(object sender, EventArgs e)
        {
            //测试线程
            Thread thread = new Thread(new ThreadStart(testComThread));
            thread.Start();
        }

        //测试端口的线程
        private void testComThread() { 
           
            FileUtils.writeLogFile("com测试");
            state = "5";
            setRunnintState();
            if (spu == null)
            {
                spu = new SerialPortUtil();
            }
            //1-16号
            port1_16 = spu.getSerialPort(com1.Text);
            //17-32号
            port17_32 = spu.getSerialPort(com2.Text);
            //输入口
            portIn = spu.getSerialPort(com3.Text);
            String text = "";
            byte[] openData = spu.getSerialOpenCode(16);
            byte[] closeData = spu.getSerialCloseCode(16);
            //打开三个Com口
            if (port1_16 != null && !port1_16.IsOpen)
            {
                try
                {
                    state = "6";
                    setRunnintState();
                    port1_16.Open();
                    port1_16.Write(openData, 0, openData.Length);
                    Thread.Sleep(1000);
                    port1_16.Write(closeData, 0, closeData.Length);
                    text += "1-16工作正常,";
                   
                    FileUtils.writeLogFile("1-16工作正常");
                }
                catch (Exception excep)
                {
                    MessageBox.Show(excep.ToString());
                    text += "1-16工作异常,";
                    FileUtils.writeLogFile("1-16工作异常");
                }
                finally {
                    spu.close(port1_16);
                }

            }
            if (port17_32 != null && !port17_32.IsOpen)
            {
                try
                {
                    state = "7";
                    setRunnintState();
                    port17_32.Open();
                    port17_32.Write(openData, 0, openData.Length);
                    Thread.Sleep(1000);
                    port17_32.Write(closeData, 0, closeData.Length);
                    text += "17-32工作正常,";
                    FileUtils.writeLogFile("17-32工作正常");
                }
                catch (Exception excep)
                {
                    MessageBox.Show(excep.ToString());
                    text += "17-32工作异常,";
                    FileUtils.writeLogFile("17-32工作异常");
                }
                finally {
                    spu.close(port17_32);
                }

            }
            if (portIn != null && !portIn.IsOpen)
            {
                try
                {
                    state = "8";
                    setRunnintState();
                    portIn.Open();
                    portIn.Write(openData, 0, openData.Length);
                    Thread.Sleep(1000);
                    portIn.Write(closeData, 0, closeData.Length);
                    text += "输入工作正常";
                    FileUtils.writeLogFile("输入工作正常");
                }
                catch (Exception excep)
                {
                    MessageBox.Show(excep.ToString());
                    text += "输入工作异常";
                    FileUtils.writeLogFile("输入工作异常");
                }
                finally {
                    spu.close(portIn);
                }
            }
              state = "9";
              setRunnintState();
              testDatabase();
              testResult.Text = text;
              state = "1";
              setRunnintState();
                  
        }


        //选择文件
        private void fileselectButton_Click(object sender, EventArgs e)
        {
                    
          if (ofd.ShowDialog() == DialogResult.OK) {
               fileName.Text = ofd.FileName;
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (validateData())
            MessageBox.Show("数据校验通过");
        }

        //验证数据正确性
        private Boolean validateData() {
            Boolean flag = true;
            //验证文件内容是否合法1、只能是数字和逗号分割2、数字不能大于32 3、不能有两个连续的逗号
            Regex regex = new Regex(@"^[0-9]+(,[0-9]{1,2})*$");
            //首先判断有没有文件
            if (fileName.Text == "")
            {
                MessageBox.Show("请先选择文件");
                return false;
            }
            String[] datas = FileUtils.readFile(fileName.Text);
            for (int i = 0; i < datas.Length; i++)
            {
                String d = datas[i];
                if (!regex.IsMatch(d))
                {
                    MessageBox.Show("第" + (i + 1) + "行有错误");
                    flag = false;
                    FileUtils.writeLogFile("文件验证出错");
                    break;
                }
            }
            return flag;
        
        }

        //从指定位置开始输出
        private void button3_Click(object sender, EventArgs e)
        {
            //从指定位置开始
            if (jump_rows.Text == null || "".Equals(jump_rows.Text))
            {
                MessageBox.Show("没有指定起始行");
                return;
            }
           
            if (jump_columns.Text == null || "".Equals(jump_columns.Text))
            {
                MessageBox.Show("没有指定起始列");
                return;
            }
            //首先判断有没有文件
            if (fileName.Text == "")
            {
                MessageBox.Show("请先选择文件");
                return;
            }
            //首先对数据进行验证
            if (!validateData())
            {
                return;
            }
            //判断有没有间隔时间
            if (sleepTime.Text == "")
            {
                MessageBox.Show("请填写间隔时间");
                return;
            }
            initI = int.Parse(jump_rows.Text);
            initJ = int.Parse(jump_columns.Text)+1;
           
            //创建一个线程，进行输出数据
            Thread writeDataThread = new Thread(new ThreadStart(writeData));
            writeDataThread.Start();

        }


        //当该串口接收到数据的时候触发
        private void DataReceivedHandler(object sender,
                        SerialDataReceivedEventArgs e)
        {
            try
            {
                //返回格式为 22 01 10 xx xx xx xx 校验 前2个为开关 后两个为继电器
                if (portIn != null && portIn.IsOpen)
                {

                    byte[] data = new byte[8];
                    portIn.Read(data, 0, 8);
                    //FileUtils.writeLogFile("" + data[0] + data[1] + data[2] + data[3] + data[4] + data[5] + data[6] + data[7]);
                    if (data[4] == 8)
                    {
                        //4号开关
                        canContinue = true;
                    }
                    else if (data[4] == 4)
                    {
                        //3号开关
                        canContinue = true;
                    }
                    else if (data[4] == 2)
                    {
                        //2号开关
                        canContinue = true;
                    }
                    else if (data[4] == 1)
                    {
                        //1号开关
                     //   canContinue = true;
                    }
                   

                }
                else
                {
                    FileUtils.writeLogFile("输入串口未打开");
                }
            }
            catch (Exception excep) {
                close();
            }
           

        }

        //创建用于处理数据的线程方法

        private void writeData() {
          
            if (spu == null)
            {
                spu = new SerialPortUtil();
            }
            //1-16号
            port1_16 = spu.getSerialPort(com1.Text);
            //17-32号
            port17_32 = spu.getSerialPort(com2.Text);
            //输入口
            portIn = spu.getSerialPort(com3.Text);
            //给输入口添加输入监听
            portIn.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            hasError = false;
            //是否停止
            isStoped = false;
            //打开三个Com口
            if (port1_16 != null && !port1_16.IsOpen)
            {
                try
                {
                    port1_16.Open();
                    FileUtils.writeLogFile("打开串口1成功");
                }
                catch (Exception excep) {
                    MessageBox.Show(excep.ToString());
                    FileUtils.writeLogFile("打开串口1失败");
                    hasError = true;
                }
                
            }
            if (port17_32 != null && !port17_32.IsOpen)
            {
               try
                {
                    port17_32.Open();
                    FileUtils.writeLogFile("打开串口2成功");
                }
               catch (Exception excep)
                {
                    MessageBox.Show(excep.ToString());
                    FileUtils.writeLogFile("打开串口2失败");
                    hasError = true;
                }
           
            }
            if (portIn != null && !portIn.IsOpen)
            {
                try
                {
                    portIn.Open();
                    FileUtils.writeLogFile("打开串口3成功");
                }
                catch (Exception excep)
                {
                    MessageBox.Show(excep.ToString());
                    FileUtils.writeLogFile("打开串口3失败");
                    hasError = true;
                }
            }
            if (hasError)
            {
                state = "1";
                setRunnintState();
                MessageBox.Show("串口打开失败,请检查连接情况");
                //关闭串口
                close();
                return;
            }
            //闭合一号输入口
            byte[] controlDataOpen1 = spu.getSerialOpenCode(0);
            try
            {
                portIn.Write(controlDataOpen1, 0, controlDataOpen1.Length);
                FileUtils.writeLogFile("闭合机器总电源成功");
            }
            catch (Exception excep)
            {
                close();
                FileUtils.writeLogFile("闭合机器总电源失败");
            }
            //等待一定时间后开始
            string inittimestring = inittime.Text;
            int inittimes = int.Parse(inittimestring)/1000;
            try
            {
                FileUtils.writeLogFile("电机预热中");
                for (int i = 0; i < inittimes; i++)
                {
                    Thread.Sleep(1000);
                    runningState.Text = (inittimes - i) + "秒后开始";
                    if (isStoped)
                    {
                        resetApp();
                        return;
                    }
                }
            }
            catch (Exception excep)
            {
                close();
                FileUtils.writeLogFile("电机预热失败");
            }
            //获得数据
            String[] datas = FileUtils.readFile(fileName.Text);
            FileUtils.writeLogFile("从文本中读取数据");
            state = "2";
            setRunnintState();
            //循环输出数据
            for (int i = initI; i < datas.Length; i++)
            {
                currentRows.Text = (i+1) + "行";
                String dataLine = datas[i];
                if (dataLine != null && dataLine != "")
                {
                    
                    String[] dataArray = dataLine.Split(new char[1] { ',' });
                    for (int j = initJ; j < dataArray.Length; j++)
                    {
                        //如果已经点击停止，则直接退出
                        if (isStoped) {
                            resetApp();
                            return;
                        }
                        //执行暂停
                      /**  while (isPause)
                        {
                            currentWriteState.Text = "暂停中";
                            Thread.Sleep(2000);
                            //如果已经点击停止，则直接退出
                            if (isStoped)
                            {
                                resetApp();
                                return;
                            }

                        }**/
                        currentColumns.Text = (j+1) + "列";
                        String tempData = dataArray[j];
                        //设置当前的线号
                        lineNumber.Text = tempData;
                        int data = int.Parse(tempData)-1;
                        if (data >= 0 && data < 16)
                        {
                           //获得控制代码
                            byte[] controlDataOpen = spu.getSerialOpenCode(data);
                            byte[] controlDataClose = spu.getSerialCloseCode(data);
                            
                            //如果串口处于打开状态,就发送数据
                            if (port1_16 != null && port1_16.IsOpen)
                            {
                                currentWriteState.Text = "com1正在输出";
                                try
                                {
                                    
                                    port1_16.Write(controlDataOpen, 0, controlDataOpen.Length);
                                    Thread.Sleep(Int16.Parse(sleepTime.Text));
                                    port1_16.Write(controlDataClose, 0, controlDataClose.Length);
                                }
                                catch (Exception excep) {
                                    close();
                                    FileUtils.writeLogFile("com1输出打开串口失败");
                                    currentWriteState.Text = "com1输出打开串口失败";
                                    //触发警报
                                    mu.play(0);
                                    //暂停
                                    isStoped = true;
                                    canContinue = true;
                                    continue;
                                }
                                
                                //该行正确操作完成之后,记录一下
                                FileUtils.writeDataLogFile(i + "," + j);
                                //存数据库
                                dbHelper.save(i + "," + j + "," + tempData);
                                canContinue = false;
                                //执行等待
                                while (!canContinue)
                                {
                                    //如果已经点击停止，则直接退出
                                    if (isStoped)
                                    {
                                        resetApp();
                                        return;
                                    }
                                    currentWriteState.Text = "等待指令";
                                    Thread.Sleep(100);
                                    byte[] seriorQuery1 = new byte[] { 0x55, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x66 };
                                    if (portIn != null && portIn.IsOpen)
                                    { 
                                        
                                        try
                                        {
                                            portIn.Write(seriorQuery1, 0, seriorQuery1.Length);
                                        }
                                        catch (Exception excep) {
                                            close();
                                            FileUtils.writeLogFile("接受数据打开串口失败");
                                            currentWriteState.Text = "接受数据串口接触异常";
                                            //触发警报
                                            mu.play(0);
                                            //暂停
                                            isStoped = true;
                                            //canContinue = true;
                                            //continue;
                                        }
                                       
                                    }
                                    else {
                                        FileUtils.writeLogFile("接受数据打开串口失败");
                                        //触发警报
                                        mu.play(0);
                                        //暂停
                                        isStoped = true;
                                        //canContinue = true;
                                        //continue;
                                    }
                                }

                            }
                            else {
                                FileUtils.writeLogFile("传输数据打开串口1失败");
                                //触发警报
                                mu.play(0);
                                //暂停
                                isStoped = true;
                               // continue;
                            }

                        }
                        else if (data >= 16) {
                            //获得控制代码
                            byte[] controlDataOpen = spu.getSerialOpenCode(data-16);
                            byte[] controlDataClose = spu.getSerialCloseCode(data - 16);
                            //如果串口处于打开状态,就发送数据
                            if (port17_32 != null && port17_32.IsOpen)
                            {
                                currentWriteState.Text = "com2正在输出";
                                try
                                {
                                    port17_32.Write(controlDataOpen, 0, controlDataOpen.Length);
                                    Thread.Sleep(Int16.Parse(sleepTime.Text));
                                    port17_32.Write(controlDataClose, 0, controlDataClose.Length);
                                }
                                catch (Exception excep) {
                                    close();
                                    FileUtils.writeLogFile("com2输出打开串口失败");
                                    currentWriteState.Text = "com2输出打开串口失败";
                                    //触发警报
                                    mu.play(0);
                                    //暂停
                                    isStoped = true;
                                  //  canContinue = true;
                                  //  continue;
                                
                                }
                               
                                //该行正确操作完成之后,记录一下
                                FileUtils.writeDataLogFile(i + "," + j);
                                //存数据库
                                dbHelper.save(i + "," + j + "," + tempData);
                                canContinue = false;
                                while (!canContinue)
                                {
                                    //如果已经点击停止，则直接退出
                                    if (isStoped)
                                    {
                                        resetApp();
                                        return;
                                    }
                                    currentWriteState.Text = "等待指令";
                                    Thread.Sleep(100);
                                    byte[] seriorQuery1 = new byte[] { 0x55, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x66 };
                                    if (portIn != null && portIn.IsOpen)
                                    {
                                        try
                                        {
                                            portIn.Write(seriorQuery1, 0, seriorQuery1.Length);
                                        }
                                        catch (Exception excep)
                                        {
                                            close();
                                            FileUtils.writeLogFile("接受数据打开串口失败");
                                            currentWriteState.Text = "接受数据串口接触异常";
                                            //触发警报
                                            mu.play(0);
                                            //暂停
                                            isStoped = true;
                                       //     canContinue = true;
                                        //    continue;
                                        }
                                    }
                                    else {
                                        FileUtils.writeLogFile("接受数据打开串口失败");
                                        //触发警报
                                        mu.play(0);
                                        //暂停
                                        isStoped = true;
                                      //  canContinue = true;
                                      //  continue;
                                    
                                    }
                                }

                            }
                            else {
                                FileUtils.writeLogFile("传输数据打开串口2失败");
                                //触发警报
                                mu.play(0);
                                //暂停
                                isStoped = true;
                             //   continue;
                            
                            }

                        }
                        //设置跳转值
                        setJumpinfo(i,j);
                        
                    }
                    initJ = 0;

                }
                countRows.Text = (i+1) + "行";

            }
            currentWriteState.Text = "空闲";
            //执行完毕，关闭相关的串口
            close();
            state = "1";
            setRunnintState();
         }

        //关闭
        private void close() {
            spu.close(port1_16);
            spu.close(port17_32);
            spu.close(portIn);
        
        }

        private void currentWriteState_Click(object sender, EventArgs e)
        {
           
        }


        //停止警报
        private void warningButton_Click(object sender, EventArgs e)
        {
            mu.stop();

        }

        private void runningState_Click(object sender, EventArgs e)
        {

        }

        //暂停执行
        private void button1_Click(object sender, EventArgs e)
        {
            isPause = true; 
            state = "3";
            setRunnintState();
            FileUtils.writeLogFile("暂停指令");
            
        }

        //取消暂停
        private void button5_Click(object sender, EventArgs e)
        {
            isPause = false;
            state = "2";
            setRunnintState();
            FileUtils.writeLogFile("取消暂停");
            currentWriteState.Text = "继续执行";
        }
        //设置跳转信息
        private void setJumpinfo(int m,int n) {
            jump_rows.Text = (m+1)+"";
            jump_columns.Text = (n+1)+"";
        }

        //测试数据库
        private void testDatabase() {
            if (dbHelper == null)
            {
                dbHelper = new DataBaseHelper();
            }
            dbHelper.query();
        }

        private void textBox4_TextChanged(object sender, EventArgs e)
        {

        }

        private void label15_Click(object sender, EventArgs e)
        {

        }
        //手动反馈
        private void button6_Click(object sender, EventArgs e)
        {
            canContinue = true;
        }
        //重置提示信息
        private void resetApp() {
            //mu.stop();
            currentWriteState.Text = "空闲";
            //执行完毕，关闭相关的串口
            close();
            state = "1";
            setRunnintState();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            isStoped = true;
        }

        
    }
}
